from xml.dom.minidom import parse
import xml.sax
import xml.etree.ElementTree as ET

'''
Python 有三种 XML 解析方式：SAX（simple API for XML）、DOM（Document Object Model）、ElementTree。

DOM 方式：DOM 中文译为文档对象模型，是 W3C 组织推荐的标准编程接口，它将 XML 数据在内存中解析成一个树，通过对树的操作来操作 XML。

SAX 方式：SAX 是一个用于处理 XML 事件驱动的模型，它逐行扫描文档，一边扫描一边解析，对于大型文档的解析拥有巨大优势，尽管不是 W3C 标准，但它却得到了广泛认可。

ElementTree 方式：ElementTree 相对于 DOM 来说拥有更好的性能，与 SAX 性能差不多，API 使用也很方便。
'''
# todo DOM 方式解析
# 读取文件
# dom = parse('test.xml')
# # 获取文档元素对象
# data = dom.documentElement
# # 获取 student
# stus = data.getElementsByTagName('student')
# for stu in stus:
# 	# 获取标签属性值
#     st_id = stu.getAttribute('id')
#     st_name = stu.getAttribute('name')
# 	# 获取标签中内容
#     id = stu.getElementsByTagName('id')[0].childNodes[0].nodeValue
#     name = stu.getElementsByTagName('name')[0].childNodes[0].nodeValue
#     age = stu.getElementsByTagName('age')[0].childNodes[0].nodeValue
#     gender = stu.getElementsByTagName('gender')[0].childNodes[0].nodeValue
#     print('st_id:', st_id,  ', st_name:',st_name)
#     print('id:', id, ', name:', name, ', age:', age, ', gender:',gender)

# todo  SAX 方式解析
'''
ContentHandler 类:
characters(content)：调用时机：从行开始，遇到标签之前，存在字符，content 的值为这些字符串；从一个标签，遇到下一个标签之前，
存在字符，content 的值为这些字符串；从一个标签，遇到行结束符之前，存在字符，content 的值为这些字符串。

startDocument()：文档启动的时候调用。

endDocument()：解析器到达文档结尾时调用。

startElement(name, attrs)：遇到 XML 开始标签时调用，name 是标签的名字，attrs 是标签的属性值字典。

endElement(name)：遇到 XML 结束标签时调用。
'''
# class StudentHandler(xml.sax.ContentHandler):
#     def __init__(self):
#         self.id = ""
#         self.name = ""
#         self.age = ""
#         self.gender = ""
#
#     # 元素开始调用
#     def startElement(self, tag, attributes):
#         self.CurrentData = tag
#         if tag == "student":
#             stu_name = attributes["name"]
#             print("stu_name:", stu_name)
#
#     # 元素结束调用
#     def endElement(self, tag):
#         if self.CurrentData == "id":
#             print("id:", self.id)
#         elif self.CurrentData == "name":
#             print("name:", self.name)
#         elif self.CurrentData == "age":
#             print("age:", self.age)
#         elif self.CurrentData == "gender":
#             print("gender:", self.gender)
#         self.CurrentData = ""
#
#     # 读取字符时调用
#     def characters(self, content):
#         if self.CurrentData == "id":
#             self.id = content
#         elif self.CurrentData == "name":
#             self.name = content
#         elif self.CurrentData == "age":
#             self.age = content
#         elif self.CurrentData == "gender":
#             self.gender = content
#
# if __name__ == "__main__":
#     # 创建 XMLReader
#     parser = xml.sax.make_parser()
#     # 关闭命名空间
#     parser.setFeature(xml.sax.handler.feature_namespaces, 0)
#     # 重写 ContextHandler
#     Handler = StudentHandler()
#     parser.setContentHandler(Handler)
#     parser.parse("test.xml")

# todo ElementTree 方式解析
# tree = ET.parse("test.xml")
# # 根节点
# root = tree.getroot()
# # 标签名
# print('root_tag:', root.tag)
# for stu in root:
#     # 属性值
#     print ("stu_name:", stu.attrib["name"])
#     # 标签中内容
#     print ("id:", stu[0].text)
#     print ("name:", stu[1].text)
#     print("age:", stu[2].text)
#     print("gender:", stu[3].text)

# 参考：https://www.runoob.com/python3/python3-xml-processing.html